package 基础;

import java.util.List;
import java.util.Optional;

import org.slf4j.LoggerFactory;

import ch.qos.logback.classic.LoggerContext;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
//import org.slf4j.Logger;
import ch.qos.logback.classic.Logger;//上面Logger 实例它是 org.slf4j.Logger 包下的，我们也可以获取 ch.qos.logback.classic.Logger 包下的 Logger实例。
//该 Logger实例包含特有的方法，如设置Logger实例等级等：logger.setLevel(TRACE);		//这样该Logger实例等级为 TRACE
/*
【基本的Logback组件】
Logback 的构建重点是三个主要的类上：Logger，Appender 和 Layouts。

1.组件Logger
每一个 Logger 实例都会依附在 LoggerContext 上，它管理所有 Logger实例，并且通过一个树状的层级结构来管理。

如果一个 Logger 实例的名字 A 加上一个 . 和另一个 Logger 实例名字 B ，那么 A 就是B的祖先，如果它们之间再无其他 Logger，A就是B的父级。

例如 一个Logger实例名为 com.codesy 如果 另一个实例名为 com.codesy.test ，那么前者就是后者的父级。名称是大小写敏感的。

示例：获取一个 名为 com.codesy.test 的Logger实例，查看它所依附的 LoggerContext 的所有 Logger实例*/
@Slf4j
public class Test {

   public static void main(String[] args) throws CloneNotSupportedException {
		//获取 com.codesy.test 实例
       Logger logger= (Logger) LoggerFactory.getLogger("com.codesy.test");
       //获取 Logger实例 通过 ：
       //Logger logger = LoggerFactory.getLogger("com.codesy.test")；
       //还有一种通过类的Class对象获得Logger实例，推荐使用 "com.codesy.test"这种形式，这个命名策略能够看出日志的来源是哪里。
       LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
		//getLoggerList()方法返回所有Logger实例
       List<ch.qos.logback.classic.Logger> loggerList = context.getLoggerList();
       for (ch.qos.logback.classic.Logger logger1 : loggerList) {
           System.out.println(logger1.getName());
       }
       Integer a = 127;
       Integer b = 127;
       System.out.printf("a==b: %s.\n", a == b);
       System.out.printf("a==b: %s.\n", a.equals(b));
       Integer c = 128;
       Integer d = 128;
       System.out.printf("c==d: %s.\n", c == d);
       System.out.printf("c==d: %s.\n", c.equals(b));
       
       System.out.printf("a:%s.\n", System.identityHashCode(a));
       System.out.printf("b:%s.\n", System.identityHashCode(b));
       System.out.printf("c:%s.\n", System.identityHashCode(c));
       System.out.printf("d:%s.\n", System.identityHashCode(d));
       System.out.printf("d:%s.\n", "ab".hashCode());

       //装箱与拆箱的效率实验
//       long t1 = System.currentTimeMillis();
//       //Long sum = 0L; //耗时7122毫秒
//       long sum = 0L; //耗时516毫秒
//       for (int i = 0; i < Integer.MAX_VALUE;i++) {
//      	 //如sum为Long，则需由于sum是个Long型，而i为int类型，sum += i在执行的时候，会先把i强转为long型，然后再把sum拆箱为long型
//      	 //进行相加操作，之后再自动装箱为Long型赋值给 sum。
//           sum += i;
//       }
//       long t2 = System.currentTimeMillis();        
//       System.out.println(t2-t1);//Long sum =0 L;耗时7122毫秒  long sum =0 L;耗时516毫秒
//       System.out.println("end");
//
       //浅拷贝与深拷贝
//       Writer writer1 = new Writer(18,"二哥");
//       Writer writer2 = (Writer) writer1.clone();
//
//       System.out.println("浅拷贝后：");
//       System.out.println("writer1：" + writer1);
//       System.out.println("writer2：" + writer2);
//
//       writer2.setName("三妹");
//
//       System.out.println("调整了 writer2 的 name 后：");
//       System.out.println("writer1：" + writer1);
//       System.out.println("writer2：" + writer2);
       Book book1 = new Book("编译原理",100);
       Writer writer1 = new Writer(18,"二哥",book1);
       //writer1.setBook(book1);

       Writer writer2 = (Writer) writer1.clone();
       System.out.println("浅拷贝后：");

       System.out.println("writer1：" + writer1);
       System.out.println("writer2：" + writer2);

       Book book2 = writer2.getBook();
       //System.out.println("writer2：" + writer2);
       book2.setBookName("永恒的图灵");
       book2.setPrice(70);
       
       System.out.println("writer2.book 变更后：1111");

       System.out.println("writer1：" + writer1);
       System.out.println("writer2：" + writer2);


   }
}
@Data
@AllArgsConstructor
class Writer implements Cloneable {
   private int age;
   private String name;
   private Book book;
   // getter/setter 和构造方法都已省略
//   public Writer(int age,String name){
//   	this.age=age;
//   	this.name=name;
//   }
   
//   @Override
//   public String toString() {
//       return super.toString().substring(5) + "{" +
//               "age=" + age +
//               ", name='" + name + '\'' +
//               '}';
//   }
   @Override
   public String toString() {
       return super.toString().substring(3) +
               " age=" + age +
               ", name='" + name + '\'' +
               ", book=" + book +
               '}';
   }
   @Override
	protected Object clone() throws CloneNotSupportedException {
		return super.clone();
	}
}
@Data
@AllArgsConstructor
class Book {
   private String bookName;
   private int price;

   // getter/setter 和构造方法都已省略

   @Override
   public String toString() {
       return super.toString().substring(3) +
               " bookName='" + bookName + '\'' +
               ", price=" + price +
               '}';
   }
}

//输出结果：
//ROOT
//com
//com.codesy
//com.codesy.test
/*
可以看到LoggerContext 中一共存在4个Logger实例，以 . 进行分割。获得 com.codesy.test 实例，其实同时得到了com，com.codesy实例，它们都是com.codesy.test的
前缀，通过 . 相连。还注意到一个最顶级的Logger实例 ROOT ，它是这棵树的最高层。
 */
